import re

from django import http
# from django.contrib.auth.models import User
from django.contrib.auth import login, authenticate
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import logout
from django.core.paginator import Paginator, EmptyPage
from django.db import DatabaseError
from django.shortcuts import render, redirect

# Create your views here.
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from apps.areas.models import Address
from apps.orders.models import OrderInfo
from apps.shoppingcart.utils import merge_cart_cookie_to_redis
from apps.users.models import User
from utils import constants
from utils.response_code import RETCODE


class RegisterView(View):
    """用户注册"""

    def get(self, request):
        """
        提供注册界面
        :param request: 请求对象
        :return: 注册界面
        """
        return render(request, 'register.html')

    def post(self, request):
        sms_code = request.POST.get("sms_code")
        username = request.POST.get("username")
        # print(username)
        password = request.POST.get("password")
        # print(password)
        password2 = request.POST.get("password2")
        # print(password2)
        mobile = request.POST.get("mobile")
        # print(mobile)
        allow = request.POST.get("allow")
        # print(allow)
        # 判断参数是否齐全
        if not all([username, password, password2, mobile, allow, sms_code]):
            print("*" * 30)
            return http.HttpResponseBadRequest('缺少必传参数')
        # 判断用户名是否是5-20个字符
        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username):
            return http.HttpResponseBadRequest('请输入5-20个字符的用户名')
        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseBadRequest('请输入8-20位的密码')
        # 判断两次密码是否一致
        if password != password2:
            return http.HttpResponseBadRequest('两次输入的密码不一致')
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('请输入正确的手机号码')
        # 判断是否勾选用户协议
        if allow != 'on':
            return http.HttpResponseBadRequest('请勾选用户协议')
        # return http.HttpResponse("ok")
        # if len(sms_code) != 6:
        #     return http.HttpResponseBadRequest('你输入的验证码有误')
        print("123")
        redis_conn = get_redis_connection('code')
        sms_code_saved = redis_conn.get('sms_%s' % mobile)
        if sms_code_saved is None:
            return render(request, 'register.html', {'sms_code_errmsg': '无效的短信验证码'})
        if sms_code != sms_code_saved.decode():
            return render(request, 'register.html', {'sms_code_errmsg': '输入短信验证码有误'})
        # 保存注册数据
        try:
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
        except DatabaseError:
            return render(request, 'register.html', {'register_errmsg': '注册失败'})
        login(request, user)
        # return http.HttpResponse("注册成功，重新定向到首页")
        response = redirect(reverse('index:index'))
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)
        return response


class UsernameCountView(View):
    # 判断用户名是否注册过
    def get(self, request, username):
        count = User.objects.filter(username=username).count()
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': "ok", 'count': count})


class MobileCountView(View):
    # 判断手机号是否注册过
    def get(self, request, mobile):
        count = User.objects.filter(mobile=mobile).count()
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': "ok", 'count': count})


class LoginView(View):
    """用户登录"""

    def get(self, request):
        """
        提供登录界面
        :param request: 请求对象
        :return: 登录界面
        """
        return render(request, 'login.html')

    def post(self, request):
        # 1.获取数据
        username = request.POST.get("username")
        password = request.POST.get("password")
        remembered = request.POST.get("remembered")
        # 2.校检数据
        if not all([username, password]):
            return http.HttpResponseBadRequest("缺少参数")
        if not re.match(r'[0-9A-Za-z_-]{5,20}$', username):
            return render(request, 'login.html', {'account_errmsg': '请输入正确的用户名或手机号'})
        if not re.match(r'[0-9A-Za-z]{8,20}$', password):
            return render(request, 'login.html', {'account_errmsg': '请输入正确的密码'})
        # 3.对用户名和密码进行判断
        user = authenticate(username=username, password=password)
        if user is None:
            return render(request, 'login.html', {'account_errmsg': '用户名或者密码错误'})
        login(request, user)
        if remembered != "on":
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)

        # 方法一 登录好后只能返回到主页
        # # 首页用户名展示
        # response = redirect(reverse('index:index'))
        # 方法二 登录好后可以跳转到之前的页面
        # 响应登录结果
        next = request.GET.get('next')
        if next:
            response = redirect(next)
        else:
            response = redirect(reverse('index:index'))
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)
        response = merge_cart_cookie_to_redis(request=request, user=user, response=response)
        return response


class LogoutView(View):
    """退出登录"""

    def get(self, request):
        """实现了退出了功能"""
        # 清除session
        logout(request)
        # 退出登录，重新定向到主页
        response = redirect(reverse('index:index'))
        response.delete_cookie("username")
        return response


class UserCenterView(LoginRequiredMixin, View):
    """用户中心"""

    def get(self, request):
        """提供个人信息界面"""
        context = {
            'username': request.user.username,
            'mobile': request.user.mobile,
            'email': request.user.email,

            'email_active': request.user.email_active,
        }
        return render(request, 'base_user_center.html', context=context)


class AddressView(LoginRequiredMixin, View):
    """用户收货地址"""

    def get(self, request):
        """提供收货地址界面"""
        # 获取用户地址的列表
        addresses = Address.objects.filter(user=request.user, is_deleted=False)
        address_dict_list = []
        for address in addresses:
            address_dict = {
                "id": address.id,
                "title": address.title,
                "receiver": address.receiver,
                "province": address.province.name,
                "province_id": address.province_id,
                "city": address.city.name,
                "city_id": address.city_id,
                "district": address.district.name,
                "district_id": address.district_id,
                "place": address.place,
                "mobile": address.mobile,
                "tel": address.tel,
                "email": address.email
            }
            address_dict_list.append(address_dict)
        context = {
            'default_address_id': request.user.default_address_id,
            'addresses': address_dict_list,
        }
        print(context)
        return render(request, 'base_user_center_site.html', context)


class ChangePasswordView(LoginRequiredMixin, View):
    def get(self, request):
        return render(request, 'base_user_center_pass.html')

    def post(self, request):
        # 获取参数
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        new_password2 = request.POST.get('new_password2')
        # 验证参数
        if not all([old_password, new_password, new_password2]):
            return http.HttpResponseForbidden('缺少参数')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_password):
            return http.HttpResponseBadRequest('密码不是8-20位')
        if new_password != new_password2:
            return http.HttpResponseBadRequest('新的密码两次不一样')
        # 验证旧密码是否正确
        if not request.user.check_password(old_password):
            return render(request, 'user_center_pass.html', {'origin_password_errmsg': '原始密码错误'})
        # 保存新的密码
        try:
            request.user.check_password(old_password)
            request.user.save()
        except Exception as e:
            return render(request, 'user_center_pass.html', {'change_password_errmsg': '修改密码失败'})
        # 5.退出登陆,删除登陆信息
        logout(request)
        # 6.跳转到登陆页面
        response = redirect(reverse('users:login'))

        response.delete_cookie('username')

        return response


class UserOrderInfoView(LoginRequiredMixin, View):
    """我的订单"""

    def get(self, request, page_num):
        """提供我的订单页面"""
        user = request.user
        # 查询订单
        orders = user.orderinfo_set.all().order_by("-create_time")
        # 遍历所有订单
        for order in orders:
            # 绑定订单状态
            order.status_name = OrderInfo.ORDER_STATUS_CHOICES[order.status - 1][1]
            # 绑定支付方式
            order.pay_method_name = OrderInfo.PAY_METHOD_CHOICES[order.pay_method - 1][1]
            order.sku_list = []
            # 查询订单商品
            order_goods = order.skus.all()
            # 遍历订单商品
            for order_good in order_goods:
                sku = order_good.sku
                sku.count = order_good.count
                sku.amount = sku.price * sku.count
                order.sku_list.append(sku)

        # 分页
        page_num = int(page_num)
        try:
            paginator = Paginator(orders, constants.ORDERS_LIST_LIMIT)
            page_orders = paginator.page(page_num)
            total_page = paginator.num_pages
        except EmptyPage:
            return http.HttpResponseNotFound('订单不存在')

        context = {
            "page_orders": page_orders,
            'total_page': total_page,
            'page_num': page_num,
        }
        return render(request, "user_center_order.html", context)
